﻿//***********************************************************************
// Assembly         : IGolovkine.AoA.Core
// Author           : Ilia
// Created          : 06-11-2011
//
// Last Modified By : Ilia
// Last Modified On : 01-07-2010
// Description      : 
//
// Copyright        : (c) Microsoft. All rights reserved.
//***********************************************************************
using System;
using System.Reactive.Linq;

namespace IGolovkine.AoA.Tcp
{
    public class TcpOutboundTunnel : IDisposable
    {
        private readonly IDisposable _connectionSubscription;
        private readonly IDisposable _tunnelSubscription;
        private readonly Lazy<string> _description;

        public TcpOutboundTunnel(IMessageChannel tunnel, IChannel<byte[]> connection, CorrelationId connectionId)
        {
            _connectionSubscription = tunnel.Output
                .OfType<TcpConnectionMessage>()
                .Where(message => message.ConnectionId == connectionId)
                .Subscribe(message =>
                    {
                        if (message is TcpConnectionData)
                        {
                            connection.Input.OnNext(((TcpConnectionData) message).GetData());
                        }
                        else if (message is TcpConnectionTerminated)
                        {
                            connection.Input.OnCompleted();
                        }
                    });

            _tunnelSubscription = connection.Output
                .Subscribe(
                    data => tunnel.Input.OnNext(new TcpConnectionData(connectionId, data)), 
                    ex => {},
                    ()=> tunnel.Input.OnNext(new TcpConnectionTerminated(connectionId))); 

            _description = new Lazy<string>(() => connection.ToString());
        }

        public override string ToString()
        {
            return _description.Value;
        }

        public void Dispose()
        {
            _connectionSubscription.Dispose();
            _tunnelSubscription.Dispose();
        }
    }
}
